# trainData.py
# Jieun Oh

from numpy import array, size, zeros, arange, amax, cast
from quantize import *            # ScaleFactor, Mantissa, Dequantize, vMantissa, vDequantize, smallestScale
from huffmanCode import *

def trainNoise(arr):
    """
    Trains the data from a noise file and creates a Huffman table
    """
    n = size(arr)
    numBlocks = n/25

    blocks = zeros([numBlocks, 25])
    scales = zeros([numBlocks, 1])
    mantissaVecs = zeros([numBlocks, 25]) 

    for i in arange(numBlocks):
       block = arr[i*25:(i+1)*25]
       blocks[i,:] = block
       largest = amax(block)

       # possibly adjust this when making our huffman table
       nScaleBits = 3
       nMantBits = 2     # effectively 4 though, because sign-bit is not used

       scale = ScaleFactor(largest, nScaleBits, nMantBits)  
       scales[i,:] = scale

       mantissaVec = vMantissa(block, scale, nScaleBits, nMantBits)
       mantissaVecs[i,:] = mantissaVec
   

    # noise envelope will never be negative? Then we don't need to waste a bit for sign... 
    # effectively, use nMantBits-1 bits for mantissas
    # calculates frequency of "symbols" in mantissaVecs
    count = {}
    for i in arange(2**(nMantBits-1)):
       count[i] = 0

    for r in arange(numBlocks):
       for c in arange(25):
          count[mantissaVecs[r,c]] += 1

    # print count        # dictionary

    a = count.items()  # list of (key, value) pairs in the "count" dictionary
    h = Huffman(a)

    # code = h.Symbol2Code[10]
    # symbol = h.Code2Symbol[code]
    # print h.Code2Symbol[h.Symbol2Code[10]]  # should be 10

    hcMantissaVecs = zeros([numBlocks, 25], dtype=int)
    totCodedBits = 0
    for r in arange(numBlocks):
       for c in arange(25):
          hcMantissaVecs[r,c] = h.Symbol2Code[mantissaVecs[r,c]]
          copy = hcMantissaVecs[r,c]
          totCodedBits += len(str(copy))

    # print "uncodedMantissaBits", 25*numBlocks*(nMantBits-1)                       # 2169800
    # print "codedMantissaBits", totCodedBits                                       # 1044649
    #   
    # print "totalUncodedBits", 25*numBlocks*(nMantBits-1) + numBlocks*nScaleBits   # 2234894
    # print "totalCodedBits", totCodedBits + numBlocks*nScaleBits                   # 1109743
    return (h.Code2Symbol, hcMantissaVecs)

def trainData(arr):
    """
    Trains the data from a wav file and creates a Huffman table
    """
    n = size(arr)
    numPerBlock = 1440
    numBlocks = n/numPerBlock                                          # 862 for small, 10849 for entire biggy
    print numBlocks

    blocks = zeros([numBlocks, numPerBlock])
    ## scales = zeros([numBlocks, 1])
    mantissaVecs = zeros([numBlocks, numPerBlock]) 

    for i in arange(numBlocks):
       block = arr[i*numPerBlock:(i+1)*numPerBlock]
       blocks[i,:] = block
       ##largest = amax(block)

       # possibly adjust this when making our huffman table
       nScaleBits = 3
       nMantBits = 5     # effectively 4 though, because sign-bit is not used

       ##scale = ScaleFactor(largest, nScaleBits, nMantBits)  
       ##scales[i,:] = scale

       ##mantissaVec = vMantissa(block, scale, nScaleBits, nMantBits)
       mantissaVecs[i,:] = block ##mantissaVec


    # noise envelope will never be negative? Then we don't need to waste a bit for sign... 
    # effectively, use nMantBits-1 bits for mantissas

    # calculates frequency of "symbols" in mantissaVecs
    nMantBits = 5
    count = {}
    for i in arange(2**(nMantBits-1)):
       count[i] = 0

    for r in arange(numBlocks):
       for c in arange(numPerBlock):
          count[mantissaVecs[r,c]] += 1

    print count        # dictionary

    a = count.items()  # list of (key, value) pairs in the "count" dictionary
    """
    # save the frequency dictionary as a txt file
    text_file = open("HTable_biggy128diff_entire.txt", "w")
    text_file.write(str(a))
    text_file.close()


    # just to practice opening file to initialize an instance of Huffman. assume 1 line in the file.
    readFreqDic = open('HTable_biggy128diff_entire.txt')
    freqDic = readFreqDic.readline()       
    readFreqDic.close
    freqDic = freqDic.replace('[','')
    freqDic = freqDic.replace(']','')
    freqDic = freqDic.strip('()')
    freqDicList = freqDic.split('), (') 
    aa = []
    for i in freqDicList:
       duple = i.split(',')
       symbol = (int) (duple[0])
       freq = (int) (duple[1])
       tempTuple = (symbol, freq)
       aa.append(tempTuple)

    h = Huffman(aa)
    """
    h = Huffman(a)

    hcMantissaVecs = zeros([numBlocks, numPerBlock], dtype=int)
    totCodedBits = 0
    for r in arange(numBlocks):
       for c in arange(25):
          hcMantissaVecs[r,c] = h.Symbol2Code[mantissaVecs[r,c]]
          copy = hcMantissaVecs[r,c]
          totCodedBits += len(str(copy))

    print "uncodedMantissaBits", 25*4*numBlocks                                   # 86200  #1084900
    print "codedMantissaBits", totCodedBits                                       # 62157  #760901
    return h

if __name__ == "__main__":
    pass